package ch.dreamweb.readpractice.client.lesetraining.train.presenter;

import java.util.List;

import ch.dreamweb.readpractice.client.lesetraining.Constants;
import ch.dreamweb.readpractice.client.lesetraining.train.event.CorrectEvent;
import ch.dreamweb.readpractice.client.lesetraining.train.event.CorrectEventHandler;
import ch.dreamweb.readpractice.client.lesetraining.train.event.IncorrectEvent;
import ch.dreamweb.readpractice.client.lesetraining.train.event.IncorrectEventHandler;
import ch.dreamweb.readpractice.client.lesetraining.train.view.Unit2View;
import ch.dreamweb.readpractice.client.lesetraining.train.view.UnitView;
import ch.dreamweb.readpractice.client.managed.request.ApplicationRequestFactory;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HasWidgets;

public class Unit2Presenter extends UnitPresenter implements
		Unit2View.Unit2Presenter {

	final Unit2View view;
	private final String[] morphems20 = { "", "", "", "", "", "", "", "", "",
			"", "", "", "", "", "", "", "", "", "", "" };
	private final int[] buttonNumbers = new int[20];
	private int record = 0;
	private int random = 0;
	private int count = 0;
	private int index = 0;
	private int buttonNumber = 0;

	Timer t = new Timer() {
		@Override
		public void run() {
			Log.info("Timer 2 läuft ab");
			if (index <= level) {
				view.setMorphem(morphems20[level - index]);
				t.schedule(prestime);
				index++;
			} else {
				index--;
				t.cancel();
				view.setOkEnabled(false);
				view.setMorphem("");
				count = 0;
				showNine();
			}
		}
	};

	public Unit2Presenter(EventBus eventBus,
			ApplicationRequestFactory requests, Unit2View view) {
		super(eventBus, requests);
		this.view = view;
		this.view.setPresenter(this);
		bind();
	}

	private void bind() {
		getEventBus().addHandler(CorrectEvent.TYPE, new CorrectEventHandler() {

			@Override
			public void onCorrect(CorrectEvent event) {
				// TODO MKE: improve this, not nice but working
				if (event.getUnit() == 2) {
					doCorrect();
				}
			}
		});
		getEventBus().addHandler(IncorrectEvent.TYPE,
				new IncorrectEventHandler() {

					@Override
					public void onIncorrect(IncorrectEvent event) {
						// TODO MKE: improve this, not nice but working
						if (event.getUnit() == 2) {
							doIncorrect(event.getWrong());
						}
					}
				});

	}

	private void doCorrect() {
		view.addInfoNineCorrect(correctMorphems.get(count));
		if (count < (level - 1)) {
			count++;
			comment = commentCorrect();
			view.setInfo(comment, Constants.CORRECT);
			showNine();
		} else {
			record = increaseLevel();
			comment = commentCorrectFinal(record);
			view.setInfo(comment, Constants.CORRECT);
			view.setStartEnabled(true);
			view.setNineEnabled(false);
			newExercice();
		}
	}

	private void doIncorrect(String wrong) {
		String morphem = "";
		if (correctMorphems.size() > 0) {
			morphem = correctMorphems.get(count);
		} else {
			Log.warn("correct morphems is empty");
		}
		view.addInfoNineIncorrect(wrong, morphem);
		decreaseLevel();
		Log.info("in Unit2: Level: " + level + "    Step: " + step);
		comment = commentIncorrect();
		view.setInfo(comment, Constants.INCORRECT);
		view.setNineEnabled(false);
		view.setStartEnabled(true);
		newExercice();
	}

	@Override
	protected void init() {
		super.init();

		// Infos aus Datenbank auslesen
		level = editableSetting.getT2level();
		step = editableSetting.getT2step();
		stepsperlevel = editableSetting.getT2stepsperlevel();
		highestlevel = editableSetting.getT2highestlevel();
		higheststep = editableSetting.getT2higheststep();
		highestdaylevel = editableSetting.getT2highestdaylevel();
		highestdaystep = editableSetting.getT2highestdaystep();
		tottime = editableSetting.getT2tottime();
		prestime = editableSetting.getT2prestime();

		// Start exercice
		newExercice();
	}

	@Override
	public void go(final HasWidgets container) {
		super.go(container);
		container.add(view.asWidget());
	}

	@Override
	public void onOkButtonClicked() {
		if (index >= level) {
			view.setOkEnabled(false);
			view.setMorphem("");
			count = 0;
			showNine();
		} else {
			index++;
			view.setMorphem(morphems20[level - index]);
		}
	}

	@Override
	public void onStartButtonClicked() {
		morphems = info.getMorphems();
		for (int i = 0; i < 20; i++) {
			// Do-Schleife, damit nicht zweimal hintereinander das gleiche
			// Morphem kommt.
			if (i == 0) {
				random = (int) (Math.random() * 9);
			} else {
				do {
					random = (int) (Math.random() * 9);
				} while (random == buttonNumbers[(i - 1)]);
			}
			buttonNumbers[i] = random;
			morphems20[i] = morphems.get(random);
			correctMorphems.add(morphems.get(random));

		}
		view.setOkEnabled(true);
		view.setStartEnabled(false);
		view.setNineVisible(false);
		view.setInfo("");
		view.setInfoNine("");
		index = 1;
		t.schedule(500);

	}

	private void showNine() {
		List<String> subList = morphems.subList(0, 9);
		String[] all = subList.toArray(new String[0]);
		buttonNumber = buttonNumbers[count];
		view.setNine(all, buttonNumber);
	}

	@Override
	protected void saveStuff() {
		super.saveStuff();

		editableSetting.setT2level(level);
		editableSetting.setT2step(step);
		editableSetting.setT2highestlevel(highestlevel);
		editableSetting.setT2higheststep(higheststep);
		editableSetting.setT2highestdaylevel(highestdaylevel);
		editableSetting.setT2highestdaystep(highestdaystep);
		editableSetting.setT2done(true);

		writeStatistic(2);
	}

	@Override
	protected void newExercice() {
		super.newExercice();
		if (info.isTimeUp(tottime)) {
			Log.info("Time's up... Ending Unit 2");
			saveStuff();
			info.setUnitActive(0);
			view.setMenuVisible(true);
			view.setFocusMenu();
			view.setStartEnabled(false);
		} else {
			count = 0;
			view.setInfoLevel("Level: " + level + " / " + step);
			correctMorphems.clear();
			view.setMorphem("");
			view.setMorphem20("");
			view.setFocusStart();
		}
	}

	@Override
	protected UnitView getView() {
		return view;
	}

	@Override
	protected void showElephant(int type) {
		view.showElephant(type);
	}
}
